/***************************************************************************
 * Open Object Oriented ANSI C                                             *
 ***************************************************************************
 * Code given under the terms of GNU General Public Licence (GPLv3)        *
 * and without any waranties of any kind including but not limitative to   *
 * waranties on merchandability or any particular applications fitness.    *
 * For more information on GNU/GPL go on :                                 *
 * "http://www.gnu.org/copyleft/gpl.html"                                  *
 *                                                                         *
 * You are allowed to use it for any purposes in the terms of GNU/GPLv3    *
 * (or more).                                                              *
 * This text MUST stay in state on copyed sources (or sources using it)    *
 * and must not be altered.                                                *
 * You are allowed to add your name at the end of the Copylefs list.       *
 ***************************************************************************
 * Copylefts List :                                                        *
 ***************************************************************************
 * 2010-03-20 Patrick PIGNOL <pignol_patrick@hotmail.com> (Original)       *
 * (Type your name here if needed)                                         *
 ***************************************************************************/
#include <signal.h>
#include "Mem.h"
#include "ExceptionStateRecover.h"

static ExceptionStateRecoverVirtualTable* ExceptionStateRecoverVirtualTableInstance;

ExceptionStateRecover* ExceptionStateRecoverNew(unsigned long pArgsCount, va_list* pParameters)
{
    ExceptionStateRecover* this;
    this = (ExceptionStateRecover*)malloc(sizeof(ExceptionStateRecover));
    if (!this)
    {
        raise(SIGABRT);
    }
    this->VirtualTable = ExceptionStateRecoverInitialize(this, pArgsCount, pParameters);
    this->Constructor = ExceptionStateRecoverConstructor;
    this->Destructor = ExceptionStateRecoverDestructor;
    this->Clone = ExceptionStateRecoverClone;
    this->SafeState = ExceptionStateRecoverSafeState;
    this->ExceptionHandlers = ExceptionStateRecoverExceptionHandlers;
    this->Constructor(this, pArgsCount, pParameters);
    return this;
}

ExceptionStateRecoverVirtualTable* ExceptionStateRecoverInitialize(ExceptionStateRecover* this, unsigned long pArgsCount, va_list* pParameters)
{
    if(!ExceptionStateRecoverVirtualTableInstance)
    {
        ExceptionStateRecoverVirtualTableInstance = malloc(sizeof(ExceptionStateRecoverVirtualTable));
        if(!ExceptionStateRecoverVirtualTableInstance)
        {
            raise(SIGABRT);
        }
        ExceptionStateRecoverVirtualTableInstance->Interface = 0;

        ExceptionStateRecoverVirtualTableInstance->TypeID = EXCEPTIONSTATERECOVER_TYPEID;

        ExceptionStateRecoverVirtualTableInstance->AncestorTable = ClassInitialize((Class*)this, pArgsCount, pParameters);

        ExceptionStateRecoverVirtualTableInstance->ReferenceCount = 0;

        ExceptionStateRecoverVirtualTableInstance->new = ExceptionStateRecoverNew;
        ExceptionStateRecoverVirtualTableInstance->Initialize = ExceptionStateRecoverInitialize;
        ExceptionStateRecoverVirtualTableInstance->Garbage = (void(*)(ExceptionStateRecover*))ExceptionStateRecoverVirtualTableInstance->AncestorTable->Garbage;
        ExceptionStateRecoverVirtualTableInstance->TypeOf = (unsigned long int (*)(ExceptionStateRecover*))ExceptionStateRecoverVirtualTableInstance->AncestorTable->TypeOf;
        ExceptionStateRecoverVirtualTableInstance->IsSameTypeThanTypeID = (bool (*)(ExceptionStateRecover*, unsigned long int))ExceptionStateRecoverVirtualTableInstance->AncestorTable->IsSameTypeThanTypeID;
        ExceptionStateRecoverVirtualTableInstance->IsKindOfTypeID = (bool (*)(ExceptionStateRecover* this, unsigned long int))ExceptionStateRecoverVirtualTableInstance->AncestorTable->IsKindOfTypeID;
        ExceptionStateRecoverVirtualTableInstance->IsSameTypeThan = (bool (*)(ExceptionStateRecover* this, Class*))ExceptionStateRecoverVirtualTableInstance->AncestorTable->IsSameTypeThan;
        ExceptionStateRecoverVirtualTableInstance->IsKindOf = (bool (*)(ExceptionStateRecover* this, Class*))ExceptionStateRecoverVirtualTableInstance->AncestorTable->IsKindOf;
    }
    ExceptionStateRecoverVirtualTableInstance->ReferenceCount++;
    return ExceptionStateRecoverVirtualTableInstance;
}

void ExceptionStateRecoverConstructor(ExceptionStateRecover* this, unsigned long int pArgsCount, va_list* pParameters)
{
    this->aExceptionHandlers = new((void*(*)(unsigned long int, va_list*))StackNew,0);
}

void ExceptionStateRecoverDestructor(ExceptionStateRecover* this)
{
    this->Clone = 0;
    while(this->aExceptionHandlers->Count(this->aExceptionHandlers))
    {
        delete(this->aExceptionHandlers->Pop(this->aExceptionHandlers));
    }
    delete ((void*)this->aExceptionHandlers);
}

ExceptionStateRecover* ExceptionStateRecoverClone(ExceptionStateRecover* this)
{
    ExceptionStateRecover* vClone = 0;
    ExceptionHandler* vExceptionHandler = 0;
    Stack* vTempStack = new((void*(*)(unsigned long int, va_list*))StackNew, 0);
    vClone = new ((void*(*)(unsigned long int, va_list*))ExceptionStateRecoverNew, 0);
    while(this->aExceptionHandlers->Count(this->aExceptionHandlers))
    {
        vExceptionHandler = (ExceptionHandler*)this->aExceptionHandlers->Pop(this->aExceptionHandlers);
        vTempStack->Push(vTempStack, (Class*)vExceptionHandler);
        vClone->ExceptionHandlers(vClone)->Push((Stack*)vClone->ExceptionHandlers(vClone), (Class*)vExceptionHandler->Clone(vExceptionHandler));
    }
    while(vTempStack->Count(vTempStack))
    {
        vExceptionHandler =  (ExceptionHandler*)vTempStack->Pop(vTempStack);
        this->aExceptionHandlers->Push(this->aExceptionHandlers, (Class*)vExceptionHandler);
    }
    delete((void*)vTempStack);
    return vClone;
}

jmp_buf* ExceptionStateRecoverSafeState(ExceptionStateRecover* this)
{
    return &this->aSafeState;
}

const Stack* ExceptionStateRecoverExceptionHandlers(ExceptionStateRecover* this)
{
    return this->aExceptionHandlers;
}
